
#pragma once

#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Weffc++"
#endif


namespace tools
{
    namespace variant_detail
    {
        struct Dimmy
        {
            typedef V::Str Str;
            static Str& Default() { static Str s; return s; }
        };
//-----------------------------------------------------------------------------------------
        template<class T, int TYPE_CATEGORY>struct GetElement;
//-----------------------------------------------------------------------------------------

        template<class T>struct GetElement<T,ePRIMITIVE>: Dimmy
        {
            static const Str& GetKey(const void* const)
            {
                return Default();
            }
            static const Variant& GetVariant(const void* const data)
            {
                return *static_cast<const Variant*>(data);
            }
        };
//-----------------------------------------------------------------------------------------
        template<class T>struct GetElement<T,eLINEAR>: GetElement<T,ePRIMITIVE>{};
//-----------------------------------------------------------------------------------------
        template<class T>struct GetElement<T,eASSOCIATIVE>: Dimmy
        {
            typedef typename T::value_type
                ValueType;

            static const Str& GetKey(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.first;
            }
            static const Variant& GetVariant(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.second;
            }
        };
//-----------------------------------------------------------------------------------------
        template<class T>struct GetElement<T,eKEY_VARIANT>
        {
            typedef V::Str Str;
            typedef T ValueType;

            static const Str& GetKey(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.first;
            }
            static const Variant& GetVariant(const void* const data)
            {
                const ValueType& pair = *static_cast<const ValueType*const>(data);
                return pair.second;
            }
        };
//-----------------------------------------------------------------------------------------

    }//namespace value_detail
}//namespace tools


#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic pop
#endif
